package com.gec.config;


import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.gec.realm.MyRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Base64;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {

    //配置Shiro的安全管理器
    @Bean
    public SecurityManager securityManager(Realm myRealm, RememberMeManager rememberMeManager) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //设置一个Realm，这个Realm是最终用于完成我们的认证号和授权操作的具体对象
        securityManager.setRealm(myRealm);
        //使用EhCache缓存用户授权/认证的信息

        //注入记住我管理器
        securityManager.setRememberMeManager(rememberMeManager);

        return securityManager;
    }

    //配置一个自定义的Realm的bean，最终将使用这个bean返回的对象来完成我们的认证和授权
    @Bean("myRealm")
    public Realm myRealm() {
        return new MyRealm();
    }

    //配置一个Shiro的过滤器bean，这个bean将配置Shiro相关的一个规则的拦截
    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        //创建Shiro的拦截的拦截器 ，用于拦截我们的用户请求
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        //设置Shiro的安全管理，设置管理的同时也会指定某个Realm
        shiroFilter.setSecurityManager(securityManager);
        //用于设置一个登录的请求地址，这个地址可以是一个html或jsp的访问路径，也可以是一个控制器的路径
        //作用是用于通知Shiro我们可以使用这里路径转向到登录页面，但Shiro判断到我们当前的用户没有登录时就会自动转换到这个路径
        //要求用户登录成功
        shiroFilter.setLoginUrl("/");
        //配置登录成功以后转向的请求地址
        shiroFilter.setSuccessUrl("/index");
        //没有权限跳转到refuse
        shiroFilter.setUnauthorizedUrl("/refuse");

        //定义一个Map集合，这个Map集合中存放的数据全部都是规则，用于设置通知Shiro什么样的请求可以访问什么样的请求不可以访问
        Map<String, String> map = new LinkedHashMap<String, String>();

        //  /login 表示某个请求的名字    anon 表示可以使用游客什么进行登录（这个请求不需要登录）
        map.put("/login", "anon");
        map.put("/bootstrap/**", "anon");
        map.put("/css/**", "anon");
        map.put("/static/**", "anon");
        map.put("/js/**", "anon");

        //配置登出请求   logout登出后清理用户内存
        map.put("/logout", "logout");

        map.put("/baoxiao/**", "authc");
        map.put("/leavebill/**", "authc");
        map.put("/apply_leavebill", "authc,perms[leave:apply]");
        map.put("/myLeaveBill", "authc,perms[leave:billquery]");
        map.put("/myTaskList", "authc,perms[leave:tasklist]");
        map.put("/add_process", "authc,perms[user:publish]");
        map.put("/workflow_list", "authc,perms[user:processlist]");
        map.put("/findUserList", "authc,perms[user:query]");
        map.put("/toAddRole", "authc,perms[user:create]");
        map.put("/findRoles", "authc,perms[user:rolelist]");

        //如果没有指定/** 那么如果某个请求不符合上面的拦截规则Shiro将放行这个请求
        //map.put("/**","user");

        shiroFilter.setFilterChainDefinitionMap(map);
        System.out.println("加载权限过滤器完毕....");
        return shiroFilter;
    }

    /**
     * COOKIE对象,配置cookie生成模板,用于配置免登录
     * @return
     */
    @Bean
    public SimpleCookie rememberMeCookie() {
        //这个参数是cookie的名称，对应前端的checkbox的name = rememberMe
        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");

        //设为true后，只能通过http访问，javascript无法访问
        //防止xss读取cookie
        simpleCookie.setHttpOnly(true);
        simpleCookie.setPath("/");
        //设值有效时间为30天
        simpleCookie.setMaxAge(259200);

        return simpleCookie;
    }

    /**
     * FormAuthenticationFilter 过滤器 过滤记住我
     * @return
     */
    /*@Bean
    public FormAuthenticationFilter formAuthenticationFilter(){
        FormAuthenticationFilter formAuthenticationFilter = new FormAuthenticationFilter();
        //对应前端的checkbox的name = rememberMe
        formAuthenticationFilter.setRememberMeParam("rememberMe");
        return formAuthenticationFilter;
    }*/

    /**
     * rememberMe管理器
     * @return
     */
    @Bean
    public CookieRememberMeManager rememberMeManager(SimpleCookie rememberMeCookie){
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();

        cookieRememberMeManager.setCookie(rememberMeCookie);
        System.out.println("设置cookie");
        //配置cookie加密的密钥
        cookieRememberMeManager.setCipherKey(Base64.getDecoder().decode("2AvVhdsgUs0FSA3SDFAdag=="));
        return cookieRememberMeManager;
    }

    /**
     * 配置加密器
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        matcher.setHashAlgorithmName("md5");
        matcher.setHashIterations(1);
        return matcher;
    }

    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }

}
